#include<stdio.h> 
#include<fcntl.h> 
#include<unistd.h> 
#include<termios.h> // using the termios.h library
#include <errno.h>

#include <stdlib.h>
#include <string.h>
#define ATGM331C_BAUD B9600
#include "parser.h"
#include "data_proc.h"
#include "serial.h"
#include <sys/select.h>
int g_fd_uart4 = -1;

void procStrFromUart2(char * buff, int sizeRecv, int fd_file)
{
  char buffStr[1024];
  char plaintext[128];
  char locPack[128];
  ggaInfo stGgaInfo;
  int indexTenthComma;
  
  vtgInfo stVtgInfo;
  int checkRet = checkHead(buff, sizeRecv);
  if(checkRet == GGA)
  {
    unsigned char usrKey[16] = {0};
    unsigned char ciphertext[64] = {0};
	int sendCount = 0;
    memset(&stGgaInfo, 0, sizeof(ggaInfo));
    parseGGA(buff, sizeRecv, &stGgaInfo);
    printf("len=%d,%s\n",sizeRecv,buff);
    memset(buffStr,0,1024);
    formatGgaStr(&stGgaInfo,buffStr); 
    memset(plaintext,0,128);
    indexTenthComma =  findTenthComma(buff, sizeRecv);   
    if(indexTenthComma == -1)
    {
      memcpy(plaintext,buff,64);   
    }
    else
    {
      int remain = 64 - indexTenthComma-1;
      memcpy(plaintext,buff,indexTenthComma+1);
      memset(plaintext+indexTenthComma+1,',',remain); 
    }
    //printf("len plain[%d],%s\n",strlen(plaintext),plaintext);
    getUserKey(usrKey);
    aes128_enc_64bytes(usrKey,plaintext,ciphertext);
    //memcpy(plaintext,ciphertext,64);
    memset(locPack,0,128);
    enc_loc_pac(locPack,ciphertext,64,1);

	sendLocationPack(g_fd_uart4, ciphertext, 71);
    
    //send locPack to uart4 here
    //printf("len cipher[%d],%s\n",strlen(plaintext),plaintext);
    //below is for debug
	if(fd_file!=-1)
    {
//	 formatHexStr(buff,sizeRecv,buffStr);
         //write(fd_file,buffStr,strlen(buffStr)+1); 

     // write(fd_file,buff,sizeRecv); 
    }
  }
  else if(checkRet == VTG)
  {
	 printf("len=%d,%s\n",sizeRecv,buff);

	 parseVTG(buff, sizeRecv, &stVtgInfo);
     
	 printf("VTG, speed is %f km/h\n",stVtgInfo.fSpeed_k);
  }
   
}


int startSerialPort(char * devName,int baudRate)
{
    int file, count; 
     if ((file = open(devName, O_RDWR |  O_NOCTTY |  O_NDELAY))<0) 
     { 
         printf("UART: Failed to open the file.%s\n",devName); 
         return -1; 
     } 
     struct termios options; // the termios structure is vital 
     tcgetattr(file, &options); // sets the parameters associated with file 
          // Set up the communications options: 
          // 9600 baud, 8-bit, enable receiver, no modem control lines 
     options.c_cflag = B9600 | CS8 | CREAD | CLOCAL; 
     options.c_iflag = IGNPAR | ICRNL; // ignore partity errors, CR -> newline 
     tcflush(file, TCIFLUSH); // discard file information not transmitted 
     tcsetattr(file, TCSANOW, &options); // changes occur immmediately  

     cfsetispeed(&options,B9600);
     cfsetospeed(&options,B9600);
	 return file;

}


int stopSerialPort(int *serialFds, int numFd)
{
    int i=0;
	for(i=0;i<numFd;i++)
    {
        if(serialFds[i]!=-1)
        {
            close(serialFds[i]);
			serialFds[i] = -1;
        }
    }
}

void * comRecvThreadProc(void * lpParam)
{
   param_com * pstParam = (param_com*)lpParam;
   int * fd_uart = pstParam->fd_uart;
   char * buff = pstParam->buff;
   int fd_file = pstParam->fd_file;   
   int count = 0, mallocFlag = 0;
   int numUarts = pstParam->uartNum;
   fd_set fds;
   int ret = 0;
   int isAllInvalid = 1;
   struct timeval tv;
   
   int i = 0;  

   for(i=0;i<numUarts;i++)
   {
      if(fd_uart[i] != -1)
      {
         isAllInvalid = 0;
      }
      //FD_SET(fd_uart[i],&fds);
   }

   if(isAllInvalid == 1)
   {
       return (void*)(0);
   }

   if(buff==NULL)
   {
      mallocFlag = 1;
	  buff = (char*)malloc(1024);
   }

   FD_ZERO(&fds);   
   tv.tv_sec = 0;
   tv.tv_usec = 200;
       
   while(1)
   {
      
      memset(buff,0,100);
      for(i=0;i<numUarts;i++)
      {
          if(fd_uart[i] != -1)
          {
             FD_SET(fd_uart[i],&fds);
          }          
      }

	  ret = select(fd_uart[i-1]+1,&fds,NULL,NULL,&tv);
	  if(ret < 0)
	  {
	     printf("Fail to select!\n");
         continue;
	  }

	  if(FD_ISSET(fd_uart[I_UART2], &fds))
	  {
	      count = read(fd_uart[I_UART2], (void*)buff, 100);
          if (count>0) 
          {  
             write(fd_file,buff,count); 
             procStrFromUart2(buff, count, fd_file);
          }
	  }

	  memset(buff,0,100);

	  if(FD_ISSET(fd_uart[I_UART4], &fds))
	  {
	      count = read(fd_uart[I_UART4], (void*)buff, 100);
          if (count>0) 
          {
             //procStrFromUart2(buff, count, fd_file);
             //proc data from uart4
          }
	  }
      
      usleep(20);
   }

   if(mallocFlag)
   {
       free(buff);
   }

   return (void*)(0);
}


